package impl.gui;

import impl.core.UDecideManager;
import impl.events.uBoxChanges.UBoxClearedChange;
import impl.events.uBoxChanges.UBoxLoadedChange;
import impl.events.uBoxChanges.UBoxSavedChange;
import impl.events.uBoxChanges.UtilityAssertionAddedChange;
import impl.events.uBoxChanges.UtilityAssertionChange;
import impl.events.uBoxChanges.UtilityAssertionRemovedChange;
import impl.gui.listeners.UDecideGUIListener;
import impl.gui.util.ChoiceCellRenderer;
import impl.gui.util.SmartScroller;
import impl.gui.util.UDecideGUIElementFactory;
import impl.gui.util.UtilityAssertionRenderer;
import impl.util.UtilityAssertion;
import interfaces.UDecideGUIInterface;
import interfaces.abstracts.AbstractUBoxChange;

import java.awt.GridLayout;
import java.util.Collection;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;

public class UDecideGUI extends JPanel implements UDecideGUIInterface {

	private UBoxPanel					uBoxPanel;
	private ChoicePanel					choicePanel;

	private UDecideLogPanel				logPanel;
	private ChoiceInformationPanel		choiceInfoPanel;

	private UtilityAssertionDialog		uAssertionDialog;
	private EditUtilityAssertionDialog	editUtilityValueDialog;

	@Override
	public void showEditUtilityAssertionDialog(UtilityAssertion oldUtilityAssertion) {
		this.editUtilityValueDialog = new EditUtilityAssertionDialog(oldUtilityAssertion);
		this.editUtilityValueDialog.setVisible(true);
	}

	@Override
	public Collection<UtilityAssertion> getSelectedUtilityAssertions() {
		return this.uBoxPanel.getSelectedUtilityAssertions();
	}

	@Override
	public void updateUtilityReasoningResults() {
		this.choicePanel.addUtilityReasoningResults(UDecideManager.getInstance().getUDecideReasoner().getAllChoiceResults().values());
	}

	public UDecideGUI() {
		new UDecideGUIListener(this);

		this.uBoxPanel = new UBoxPanel();
		this.choicePanel = new ChoicePanel();
		this.logPanel = new UDecideLogPanel();
		this.choiceInfoPanel = new ChoiceInformationPanel();

		// build scrollpane for log
		JScrollPane logPane = new JScrollPane(this.logPanel);
		logPane.setBorder(UDecideGUIElementFactory.getBorder("uDecide log"));
		logPane.setWheelScrollingEnabled(true);
		new SmartScroller(logPane);

		// add border to choice information panel
		this.choiceInfoPanel.setBorder(UDecideGUIElementFactory.getBorder("Information about last selected choice"));

		// build left GUI side
		final JSplitPane leftSideVerticalSplitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT, this.uBoxPanel, logPane);
		leftSideVerticalSplitter.setResizeWeight(0.7);
		leftSideVerticalSplitter.setDividerSize(2);

		// build right GUI side
		// JScrollPane sp = new JScrollPane(this.choiceInfoPanel);
		final JSplitPane rightSideVerticalSplitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT, this.choicePanel, this.choiceInfoPanel);
		rightSideVerticalSplitter.setResizeWeight(0.7);
		rightSideVerticalSplitter.setDividerSize(2);

		this.setLayout(new GridLayout(1, 2));
		this.add(leftSideVerticalSplitter);
		this.add(rightSideVerticalSplitter);

		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				rightSideVerticalSplitter.setDividerLocation(0.7);
				leftSideVerticalSplitter.setDividerLocation(0.7);
			}
		});
	}

	@Override
	public void showUtilityAssertionDialog() {
		if (this.uAssertionDialog == null) {
			this.uAssertionDialog = new UtilityAssertionDialog();

		}
		this.uAssertionDialog.setVisible(true);
	}

	@Override
	public void UBoxChanged(AbstractUBoxChange change) {
		if (change instanceof UtilityAssertionAddedChange) {
			this.uBoxPanel.addUtilityAssertion(((UtilityAssertionAddedChange) change).getuAssertion());
		} else if (change instanceof UtilityAssertionRemovedChange) {
			this.uBoxPanel.removeUtilityAssertion(((UtilityAssertionRemovedChange) change).getuAssertion());
		} else if (change instanceof UtilityAssertionChange) {
			this.uBoxPanel.repaint();
			this.choicePanel.repaintChoiceTable();
		} else if (change instanceof UBoxClearedChange) {
			this.uBoxPanel.removeAllUtilityAssertions();
			this.choicePanel.clearChoiceUtilityTable();
		} else if (change instanceof UBoxLoadedChange) {
			this.uBoxPanel.setUtilityAssertions(((UBoxLoadedChange) change).getUtilityAssertions());
			this.uBoxPanel.setCurrentUBoxPath(((UBoxLoadedChange) change).getPath());
		} else if (change instanceof UBoxSavedChange) {
			this.uBoxPanel.setCurrentUBoxPath(((UBoxSavedChange) change).getPath());
		}
	}

	public void setUtilityAssertionRenderer(UtilityAssertionRenderer utilityAssertionRenderer) {
		this.uBoxPanel.setUtilityAssertionRenderer(utilityAssertionRenderer);
	}

	public void setChoiceCellRenderer(ChoiceCellRenderer choiceCellRenderer) {
		this.choicePanel.setChoiceCellRenderer(choiceCellRenderer);
	}

	public void clearUtilityAssertionSelections() {
		this.uBoxPanel.clearUtilityAssertionSelections();
	}

	public void clearChoiceSelection() {
		this.choicePanel.clearChoiceSelection();
	}

	public void utilityAssertionSelected(boolean enabled) {
		this.uBoxPanel.utilityAssertionSelected(enabled);
	}

}
